From ed02ba872c02eafed45f406c68d389d0a1112a4e Mon Sep 17 00:00:00 2001 From: cashmere Date: Thu, 30 Jul 2026 18:17:45 +0200 Subject: feat: Electron desktop app, native ffmpeg export, fully static web - apps/desktop: Electron shell serving the static web build over a privileged opencut:// protocol; exports stream frames over IPC to a bundled ffmpeg (libx264/libvpx-vp9, BT.709 tagged) with backpressure. electron-builder packaging: AppImage, deb, rpm. - apps/web: dead backend deleted (better-auth, drizzle/pg, upstash, botid, freesound proxy, blog, rss, env validation); next build emits a zero-env static export; /editor/[project_id] -> /editor?project=. - Native exporter mirrors SceneExporter; activates when the preload bridge is present; web keeps the mediabunny path. - Docker self-hosting now builds and serves the static export via nginx. - Release workflow: v* tags publish static web tarball + Linux packages. - Changelog 0.4.0; README/AGENTS/CONTRIBUTING/roadmap updated. - GPUI/Rust rewrite parked on branch rust-rewrite. --- apps/web/src/app/editor/[project_id]/page.tsx | 209 -------------------------- 1 file changed, 209 deletions(-) delete mode 100644 apps/web/src/app/editor/[project_id]/page.tsx (limited to 'apps/web/src/app/editor/[project_id]') diff --git a/apps/web/src/app/editor/[project_id]/page.tsx b/apps/web/src/app/editor/[project_id]/page.tsx deleted file mode 100644 index b759b9c2..00000000 --- a/apps/web/src/app/editor/[project_id]/page.tsx +++ /dev/null @@ -1,209 +0,0 @@ -"use client"; - -import { useParams } from "next/navigation"; -import { - ResizablePanelGroup, - ResizablePanel, - ResizableHandle, -} from "@/components/ui/resizable"; -import { AssetsPanel } from "@/components/editor/panels/assets"; -import { PropertiesPanel } from "@/components/editor/panels/properties"; -import { Timeline } from "@/timeline/components"; -import { PreviewPanel } from "@/preview/components"; -import { EditorHeader } from "@/components/editor/editor-header"; -import { EditorProvider } from "@/components/providers/editor-provider"; -import { Onboarding } from "@/components/editor/onboarding"; -import { MigrationDialog } from "@/project/components/migration-dialog"; -import { usePanelStore } from "@/editor/panel-store"; -import { usePasteMedia } from "@/media/use-paste-media"; -import { MobileGate } from "@/components/editor/mobile-gate"; -import { useMemo, useState } from "react"; -import { useEditor } from "@/editor/use-editor"; -import { Cancel01Icon } from "@hugeicons/core-free-icons"; -import { HugeiconsIcon } from "@hugeicons/react"; -import { Button } from "@/components/ui/button"; -import { ChangelogNotification } from "@/changelog/components/changelog-notification"; -import { - createPreviewOverlayControl, - isPreviewOverlayVisible, - mergePreviewOverlaySources, -} from "@/preview/overlays"; -import { usePreviewStore } from "@/preview/preview-store"; -import { getGuidePreviewOverlaySource } from "@/guides"; -import { - bookmarkNotesPreviewOverlay, - getBookmarkPreviewOverlaySource, -} from "@/timeline/bookmarks/index"; - -export default function Editor() { - const params = useParams<{ project_id: string }>(); - const projectId = params.project_id; - - return ( - - -
- - -
- -
- - - -
-
-
- ); -} - -function DegradedRendererBanner() { - const isDegraded = useEditor((e) => e.renderer.isDegraded); - const [dismissed, setDismissed] = useState(false); - if (!isDegraded || dismissed) return null; - - return ( -
- For the best experience, open OpenCut in Chrome. - -
- ); -} - -function EditorLayout() { - usePasteMedia(); - const { panels, setPanel } = usePanelStore(); - const activeScene = useEditor((editor) => - editor.scenes.getActiveSceneOrNull(), - ); - const currentTime = useEditor((editor) => editor.playback.getCurrentTime()); - const activeGuide = usePreviewStore((state) => state.activeGuide); - const overlays = usePreviewStore((state) => state.overlays); - const setOverlayVisibility = usePreviewStore( - (state) => state.setOverlayVisibility, - ); - const showBookmarkNotes = isPreviewOverlayVisible({ - overlay: bookmarkNotesPreviewOverlay, - overlays, - }); - - const overlaySource = useMemo( - () => - mergePreviewOverlaySources({ - sources: [ - getGuidePreviewOverlaySource({ - guideId: activeGuide, - }), - activeScene - ? getBookmarkPreviewOverlaySource({ - bookmarks: activeScene.bookmarks, - time: currentTime, - isVisible: showBookmarkNotes, - }) - : { - definitions: [bookmarkNotesPreviewOverlay], - instances: [], - }, - ], - }), - [activeGuide, activeScene, currentTime, showBookmarkNotes], - ); - - const overlayControls = useMemo( - () => - overlaySource.definitions.map((overlay) => - createPreviewOverlayControl({ overlay, overlays }), - ), - [overlaySource.definitions, overlays], - ); - - return ( - { - setPanel({ - panel: "mainContent", - size: sizes[0] ?? panels.mainContent, - }); - setPanel({ - panel: "timeline", - size: sizes[1] ?? panels.timeline, - }); - }} - > - - { - setPanel({ panel: "tools", size: sizes[0] ?? panels.tools }); - setPanel({ panel: "preview", size: sizes[1] ?? panels.preview }); - setPanel({ - panel: "properties", - size: sizes[2] ?? panels.properties, - }); - }} - > - - - - - - - - - - - - - - - - - - - - - - - - - ); -} -- cgit v1.3.1